package com.ec.auth.security.filter;

import com.alibaba.fastjson.JSON;
import com.ec.auth.security.custom.CustomUser;
import com.ec.common.constant.HttpStatus;
import com.ec.common.core.domain.AjaxResult;
import com.ec.common.core.domain.model.LoginBody;
import com.ec.common.core.redis.RedisCache;
import com.ec.common.utils.ServletUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 登录过滤器，继承UsernamePasswordAuthenticationFilter，
 * 自定义了对用户名密码进行登录校验
 * 指定路径的拦截
 * 由于登录的方式很多 手机号码+验证 账号+密码 只做了是否携带token和租户字段认证
 * 没有继承UsernamePasswordAuthenticationFilter类 实现一个自动认证的子类
 */
public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {



    /**
     * 它还注入了一个 RedisCache 对象，用于在 Redis 中进行缓存操作
     */
    @Autowired
    private RedisCache redisCache;

    /**
     * 构造函数
     * @param authenticationManager
     */
    public TokenLoginFilter(AuthenticationManager authenticationManager) {

        this.setAuthenticationManager(authenticationManager);
        this.setPostOnly(false);

        // 指定登录接口及提交方式，可以指定任意路径
        this.setRequiresAuthenticationRequestMatcher(
                new AntPathRequestMatcher("/login","POST")
        );

        this.redisCache = redisCache;
    }


    /**
     * 登录认证
     * @param req
     * @param res
     * @return
     * @throws AuthenticationException
     */
    @Override
    public Authentication attemptAuthentication(
            HttpServletRequest req,
            HttpServletResponse res
    ) throws AuthenticationException {
        try {
            LoginBody LoginBody= new ObjectMapper().readValue(req.getInputStream(), LoginBody.class);

            Authentication authenticationToken = new UsernamePasswordAuthenticationToken(LoginBody.getUsername(), LoginBody.getPassword());
            return this.getAuthenticationManager().authenticate(authenticationToken);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }


    /**
     * 登录失败
     * @param request
     * @param response
     * @param e
     * @throws IOException
     * @throws ServletException
     */
    @Override
    protected void unsuccessfulAuthentication(
            HttpServletRequest request,
            HttpServletResponse response,
            AuthenticationException e
    ) throws IOException, ServletException {

        if(e.getCause() instanceof RuntimeException) {
            // 首先设置了一个状态码 code 为 HttpStatus.UNAUTHORIZED，表示未授权
            ServletUtils.renderString(response,JSON.toJSONString(AjaxResult.error(HttpStatus.ERROR,e.getMessage())));
        } else {
            // 首先设置了一个状态码 code 为 HttpStatus.UNAUTHORIZED，表示未授权
            ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(HttpStatus.UNAUTHORIZED, e.getMessage())));
        }
    }


    /**
     * 登录成功
     * @param request
     * @param response
     * @param chain
     * @param auth
     * @throws IOException
     * @throws ServletException
     */
    @Override
    protected void successfulAuthentication(
            HttpServletRequest request,
            HttpServletResponse response,
            FilterChain chain,
            Authentication auth
    ) throws IOException, ServletException {

        // getPrincipal返回值是一个CustomUser类实例
        // 类型转换CustomUser
        CustomUser customUser = (CustomUser) auth.getPrincipal();

        // 这里保存权限数据
//        redisCache.opsForValue().set(customUser.getUsername(), JSON.toJSONString(customUser.getAuthorities()));
//        redisCache.setCacheObject(cacheRepeatKey, cacheMap, annotation.interval(), TimeUnit.MILLISECONDS);
//
//        String token = JwtHelper.createToken(customUser.getSysUser().getId(), customUser.getSysUser().getUsername());
//
//        Map<String, Object> map = new HashMap<>();
//        map.put("token", token);
//        ResponseUtil.out(response, Result.ok(map));
//
//        AjaxResult ajax = AjaxResult.success();
//        // 生成令牌
//        String token = loginService.login(tenant, loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
//                loginBody.getUuid());
//        ajax.put(Constants.TOKEN, token);
    }
}
